﻿@page "/diagram/organization-model"

@using Syncfusion.Blazor.Diagrams
@using System.Collections.ObjectModel
@using Syncfusion.Blazor.Inputs

@inherits SampleBaseComponent;

<SampleDescription>
    <p> This sample illustrates a simple business management structure built from an external data source. A hierarchical tree layout algorithm is used to build organizational charts.</p>
    <p style="font-weight: bold;">A new blazor diagram component which provides better performance than the existing diagram control in Blazor WebAssembly App. It is available in preview mode. Check the samples <a target='_blank' href='diagramcomponent/flowchart'>here</a>.</p>
</SampleDescription>
<ActionDescription>
   <p>This example shows how to generate an organizational chart from an external data source. The spacing between the objects can also be customized in the chart. The <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/layout/organizational-chart/#layout-spacing'>HorizontalSpacing</a> and <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/layout/organizational-chart/#layout-spacing'>VerticalSpacing</a> properties of <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/layout/organizational-chart/'>DiagramLayout</a> can be used to customize the space among objects in a tree. The <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/layout/organizational-chart/#layout-orientation'>Orientation</a> property of <a target='_blank' href='https://blazor.syncfusion.com/documentation/diagram/layout/organizational-chart/'>DiagramLayout</a> can be used to change the orientation of the chart.</p>
</ActionDescription>

@*Hidden:Lines*@
<style>
    #diagram {
        display: block;
    }
    .image-pattern-style {
        background-color: white;
        background-size: contain;
        background-repeat: no-repeat;
        height: 75px;
        width: calc((100% - 18px) / 3);
        cursor: pointer;
        border: 1px solid #D5D5D5;
        background-position: center;
        float: left;
    }

        .image-pattern-style:hover {
            border-color: gray;
            border-width: 2px;
        }

    .row {
        margin-left: 0px;
        margin-right: 0px;
        display: block;
    }

    .property-panel-header {
        padding-top: 15px;
        padding-bottom: 5px;
        font-weight: 600;
        font-size: 15px;
    }

    .row-header {
        font-size: 13px;
        font-weight: 600;
    }

    .row-header1 {
        font-size: 12px;
        padding-left: 2px;
        font-weight: 400;
    }

    .e-selected-orientation-style {
        border-color: #006CE6;
        border-width: 2px;
    }


    .e-selected-pattern-style {
        border-color: #006CE6;
        border-width: 2px;
    }

    .textboxstyle {
        padding-left: 0px;
        padding-right: 0px;
        float: left;
        width: 110px;
    }

    .e-checkbox-wrapper .e-label {
        font-size: 12px;
    }

    .col-xs-6 {
        padding-left: 0px;
        padding-right: 0px;
    }

    .sb-property-border {
        border-right: 1px solid #D7D7D7;
    }
</style>
@*End:Hidden*@
<div class="col-lg-8 control-section sb-property-border">
    <div id="diagram-space" class="content-wrapper">
        <SfDiagram @ref="@Diagram" ID="diagram" Height="690px" NodeDefaults="@NodeDefaults" ConnectorDefaults="@ConnectorDefaults" Layout="@LayoutValue">
            <DiagramDataSource Id="Id" ParentId="Manager" DataSource="@DataSource">
                <DiagramDataMapSettings>
                    <DiagramDataMapSetting Property="Annotations[0].Content" Field="Role"></DiagramDataMapSetting>
                    <DiagramDataMapSetting Property="Style.Fill" Field="Color"></DiagramDataMapSetting>
                </DiagramDataMapSettings>
            </DiagramDataSource>
            <DiagramSnapSettings Constraints="SnapConstraints.None"></DiagramSnapSettings>
        </SfDiagram>
    </div>
</div>
@*Hidden:Lines*@
<div class="col-lg-4 property-section">
    <div class="property-panel-header">
        Properties
    </div>
    <div class="row property-panel-content" id="appearance">
        <div class="row" style="padding-top: 10px;">
            <div class="row row-header">
                Orientation
            </div>
            <div id="orientation">
                <div class="row" style="padding-top: 8px">
                    <div title="Top to bottom Orientation" class="@dict["topToBottom"]" @onclick="ToptoBottomClick" id="topToBottom" style="background-image: url(images/diagram/common-orientation/top-to-bottom.png); margin-right: 3px">
                    </div>
                    <div title="Bottom to top Orientation" class="@dict["bottomToTop"]" id="bottomToTop" @onclick="BottomtoTopClick" style="background-image: url(images/diagram/common-orientation/bottom-to-top.png); margin: 0px 3px">
                    </div>
                    <div title="Left to right Orientation" class="@dict["leftToRight"]" id="leftToRight" @onclick="LefttoRightClick" style="background-image: url(images/diagram/common-orientation/left-to-right.png); margin-right:0px 3px">
                    </div>
                </div>
                <div class="row" style="padding-top: 8px">
                    <div title="Right to left Orientation" class="@dict["rightToLeft"]" id="rightToLeft" @onclick="RighttoLeftClick" style="background-image: url(images/diagram/common-orientation/right-to-left.png); margin: 0px 3px">
                    </div>
                </div>
            </div>
            <div class="row row-header" style="padding-top: 10px">
                Subtree Alignment
            </div>
            <div id="pattern">
                <div class="row" style="padding-top: 8px;">
                    <div title="Sub tree alignment  : Alternate" class="@pattendict["pattern1"]" @onclick="Pattern1Click" id="pattern1" style="background-image: url(images/diagram/organization-model/vertical-alternate.png); margin-right: 3px">
                    </div>
                    <div title="Sub tree alignment  : Left" class="@pattendict["pattern2"]" @onclick="Pattern2Click" id="pattern2" style="background-image: url(images/diagram/organization-model/vertical-left.png); margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Left" class="@pattendict["pattern3"]" @onclick="Pattern3Click" id="pattern3" style="background-image: url(images/diagram/organization-model/positive-vertical-left.png); margin: 0px 3px">
                    </div>
                </div>
                <div class="row" style="padding-top: 8px">
                    <div title="Sub tree alignment  : Right" class="@pattendict["pattern4"]" id="pattern4" @onclick="Pattern4Click" style="background-image: url(images/diagram/organization-model/negative-vertical-right.png); margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Right" class="@pattendict["pattern5"]" id="pattern5" @onclick="Pattern5Click" style="background-image: url(images/diagram/organization-model/vertical-right.png); margin-right: 3px">
                    </div>
                    <div title="Sub tree alignment  : Balanced" class="@pattendict["pattern6"]" id="pattern6" @onclick="Pattern6Click" style="background-image: url(images/diagram/organization-model/horizontal-balanced.png); margin: 0px 3px">
                    </div>
                </div>
                <div class="row" style="padding-top: 8px">
                    <div title="Sub tree alignment  : Center" class="@pattendict["pattern7"]" id="pattern7" @onclick="Pattern7Click" style="background-image: url(images/diagram/organization-model/horizontal-center.png); margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Left" class="@pattendict["pattern8"]" id="pattern8" @onclick="Pattern8Click" style="background-image: url(images/diagram/organization-model/horizontal-left.png); margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Right" class="@pattendict["pattern9"]" id="pattern9" @onclick="Pattern9Click" style="background-image: url(images/diagram/organization-model/horizontal-right.png); margin: 0px 3px">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="row property-panel-content" style="padding-top: 10px">
        <div class="row row-header">
            Layout Spacing
        </div>
        <div class="row" style="padding-top: 8px">
            <div style="display: table;height: 35px;" class="textboxstyle">
                <div style="display: table-cell; vertical-align: middle">Horizontal Spacing</div>
            </div>
            <div class="textboxstyle">
                <SfNumericTextBox TValue="int?" ID="hSpacing" Format="###.##" Width="100%" Min="20" Max="60" Step="2" Value="@HValue">
                    <NumericTextBoxEvents TValue="int?" ValueChange="@HSpacingChange"></NumericTextBoxEvents>
                </SfNumericTextBox>
            </div>
        </div>
        <div class="row" style="padding-top: 8px">
            <div style="display: table;height: 35px;" class="textboxstyle">
                <div style="display: table-cell; vertical-align: middle">Vertical Spacing</div>
            </div>
            <div class="textboxstyle">
                <SfNumericTextBox TValue="int?" ID="vSpacing" Format="###.##" Width="100%" Min="20" Max="60" Step="2" Value="@VValue">
                    <NumericTextBoxEvents TValue="int?" ValueChange="VSpacingChange"></NumericTextBoxEvents>
                </SfNumericTextBox>
            </div>
        </div>
    </div>
</div>
@*End:Hidden*@
@code
    {
    static string selecteditem = "image-pattern-style  e-selected-orientation-style";
    static string unselecteditem = "image-pattern-style";
    static string selectedPattenitem = "image-pattern-style  e-selected-pattern-style";
    Dictionary<string, string> dict = new Dictionary<string, string>() {
        { "topToBottom", selecteditem },
        { "bottomToTop", unselecteditem },
        { "leftToRight", unselecteditem },
        { "rightToLeft", unselecteditem }
    };
    Dictionary<string, string> pattendict = new Dictionary<string, string>() {
       { "pattern1", unselecteditem },
       { "pattern2", unselecteditem },
       { "pattern3", unselecteditem },
       { "pattern4", unselecteditem },
       { "pattern5", selectedPattenitem },
       { "pattern6", unselecteditem },
       { "pattern7", unselecteditem },
       { "pattern8", unselecteditem },
       { "pattern9", unselecteditem },
    };

    SfDiagram Diagram;
    public int? HValue { get; set; } = 30;
    public int? VValue { get; set; } = 30;
    DiagramLayout LayoutValue = new DiagramLayout();


    TreeInfo LayoutInfo = new TreeInfo()
    {
        CanEnableSubTree = true,
        GetAssistantDetails = new AssistantsDetails() { Assistants = new string[] { "Assistant general manager" }, Root = "General manager" },
    };


    DiagramNode NodeDefaults = new DiagramNode
    {
        Height = 50,
        Width = 120,
        Annotations = new ObservableCollection<DiagramNodeAnnotation>()
        {
            new DiagramNodeAnnotation() { Offset = new NodeAnnotationOffset(){ Y =0.5, X= 0.5}, Id = "label",
             Style= new AnnotationStyle(){ Color="white"} }
        },
        LayoutInfo = new DiagramNodeLayoutInfo()
        {
            Orientation = Orientation.Vertical,
            Type = SubTreeAlignments.Right
        }
    };

    DiagramConnector ConnectorDefaults = new DiagramConnector
    {
        Type = Segments.Orthogonal,
        SourceDecorator = new ConnectorSourceDecorator() { Shape = DecoratorShapes.None },
        TargetDecorator = new ConnectorTargetDecorator() { Shape = DecoratorShapes.None }
    };

    public class OrganizationalDetails
    {
        public string Id { get; set; }
        public string Role { get; set; }
        public string Color { get; set; }
        public string Manager { get; set; }
        public string ChartType { get; set; }
        public string Type { get; set; }
        public string Orientation { get; set; }

    }
    public List<object> DataSource = new List<object>()
    {
        new OrganizationalDetails(){Id= "parent", Role= "Board", Color = "#71AF17", Manager = "",ChartType = "" },
        new OrganizationalDetails() { Id = "1",Role=  "General manager", Color = "#71AF17", Manager =  "parent", ChartType ="right"},
        new OrganizationalDetails() { Id = "11", Role= "Assistant general manager",Color =  "#71AF17", Manager =  "1",ChartType = ""},
        new OrganizationalDetails() { Id = "2", Role= "Human resource manager", Color = "#1859B7", Manager =  "1",ChartType = "right"},
        new OrganizationalDetails() { Id = "3", Role= "Trainers", Color = "#2E95D8",  Manager = "2", ChartType =""},
        new OrganizationalDetails() { Id = "4", Role= "Recruiting team",Color =  "#2E95D8", Manager =  "2",ChartType = ""},
        new OrganizationalDetails() { Id = "5", Role= "Finance asst. manager", Color = "#2E95D8", Manager =  "2", ChartType =""},
        new OrganizationalDetails() { Id = "6", Role= "Design manager", Color = "#1859B7", Manager =  "1", ChartType ="right"},
        new OrganizationalDetails() { Id = "7",Role=  "Design supervisor",Color =  "#2E95D8",  Manager = "6", ChartType =""},
        new OrganizationalDetails() { Id = "8",Role=  "Development supervisor",Color =  "#2E95D8", Manager =  "6",ChartType = ""},
        new OrganizationalDetails() { Id = "9",Role=  "Drafting supervisor", Color = "#2E95D8",  Manager = "6",ChartType = ""},
        new OrganizationalDetails() { Id = "10",Role=  "Operations manager",Color =  "#1859B7", Manager =  "1", ChartType ="right"},
        new OrganizationalDetails() { Id = "11",Role=  "Statistics department",Color =  "#2E95D8",  Manager = "10",ChartType = ""},
        new OrganizationalDetails() { Id = "12",Role=  "Logistics department",Color =  "#2E95D8", Manager =  "10", ChartType =""},
        new OrganizationalDetails() { Id = "16", Role=  "Logistics department", Color = "#1859B7", Manager =  "1", ChartType ="right"},
        new OrganizationalDetails() { Id = "17",Role=  "Overseas sales manager",Color =  "#2E95D8", Manager =  "16", ChartType =""},
        new OrganizationalDetails() { Id = "18", Role= "Petroleum manager", Color = "#2E95D8",  Manager = "16", ChartType =""},
        new OrganizationalDetails() { Id = "20",Role=  "Service department manager",Color =  "#2E95D8",  Manager = "16",ChartType = ""},
        new OrganizationalDetails() { Id = "21", Role= "Quality control department", Color = "#2E95D8",  Manager = "16", ChartType =""},

    };

    protected override void OnInitialized()
    {
        LayoutValue = new DiagramLayout()
        {
            Type = LayoutType.OrganizationalChart,
            LayoutInfo = this.LayoutInfo
        };
    }

    public async Task OnClickconnector()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Horizontal;
                node.LayoutInfo.Type = SubTreeAlignments.Right;
            }
        }
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    public void LeftToRight()
    {
        Diagram.Layout.Orientation = LayoutOrientation.LeftToRight;
        StateHasChanged();
    }

    public class ImageFields
    {
        public string Text { get; set; }
    }
    private async Task onItemClick()
    {
        IPrintOptions options = new IPrintOptions()
        {
            Margin = new Syncfusion.Blazor.Diagrams.DiagramMargin()
            {
                Left = 0,
                Right = 0,
                Top = 0,
                Bottom = 0
            },
            Region = DiagramRegions.PageSettings,
        };
        await Diagram.Print(options);

    }

    private void HSpacingChange(Syncfusion.Blazor.Inputs.ChangeEventArgs<int?> args)
    {
        HValue = (int)args.Value;
        Diagram.Layout.HorizontalSpacing = double.Parse(args.Value.ToString());
        StateHasChanged();
    }
    private void VSpacingChange(Syncfusion.Blazor.Inputs.ChangeEventArgs<int?> args)
    {
        VValue = (int)args.Value;
        Diagram.Layout.VerticalSpacing = double.Parse(args.Value.ToString());
        StateHasChanged();
    }

    private void ToptoBottomClick()
    {
        Diagram.Layout.Orientation = LayoutOrientation.TopToBottom;
        updateSelection("topToBottom");
    }
    private void LefttoRightClick()
    {
        Diagram.Layout.Orientation = LayoutOrientation.LeftToRight;
        updateSelection("leftToRight");
    }
    private void RighttoLeftClick()
    {
        Diagram.Layout.Orientation = LayoutOrientation.RightToLeft;
        updateSelection("rightToLeft");
    }
    private void BottomtoTopClick()
    {
        Diagram.Layout.Orientation = LayoutOrientation.BottomToTop;
        updateSelection("bottomToTop");
    }
    private async Task Pattern1Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Vertical;
                node.LayoutInfo.Type = SubTreeAlignments.Alternate;
                node.LayoutInfo.Offset = 20;
            }
        }
        updatePatternSelection("pattern1");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern2Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Vertical;
                node.LayoutInfo.Type = SubTreeAlignments.Left;
                node.LayoutInfo.Offset = 20;
            }
        }
        updatePatternSelection("pattern2");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern3Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Vertical;
                node.LayoutInfo.Type = SubTreeAlignments.Left;
                node.LayoutInfo.Offset = -50;
            }
        }
        updatePatternSelection("pattern3");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern4Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Vertical;
                node.LayoutInfo.Type = SubTreeAlignments.Right;
                node.LayoutInfo.Offset = -50;
            }
        }
        updatePatternSelection("pattern4");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern5Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Vertical;
                node.LayoutInfo.Type = SubTreeAlignments.Right;
                node.LayoutInfo.Offset = 20;
            }
        }
        updatePatternSelection("pattern5");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern6Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Horizontal;
                node.LayoutInfo.Type = SubTreeAlignments.Balanced;
                node.LayoutInfo.Offset = 20;
            }
        }
        updatePatternSelection("pattern6");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern7Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Horizontal;
                node.LayoutInfo.Type = SubTreeAlignments.Center;
                node.LayoutInfo.Offset = -50;
            }
        }
        updatePatternSelection("pattern7");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern8Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Horizontal;
                node.LayoutInfo.Type = SubTreeAlignments.Left;
                node.LayoutInfo.Offset = 20;
            }
        }
        updatePatternSelection("pattern8");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern9Click()
    {
        Diagram.BeginUpdate();
        foreach (var node in Diagram.Nodes)
        {
            if (!node.LayoutInfo.HasSubTree)
            {
                node.LayoutInfo.Orientation = Orientation.Horizontal;
                node.LayoutInfo.Type = SubTreeAlignments.Right;
                node.LayoutInfo.Offset = 20;
            }
        }
        updatePatternSelection("pattern9");
        Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private void updatePatternSelection(string id)
    {
        for (int i = 0; i < pattendict.Count; i++)
        {
            var value = pattendict.Values.ElementAt(i);
            var key = pattendict.Keys.ElementAt(i);
            if (pattendict.ContainsKey(id) && key == id)
            {
                value = selectedPattenitem;
            }
            else
            {
                value = unselecteditem;
            }
            pattendict.Remove(key);
            pattendict.Add(key, value);
        }

        StateHasChanged();
    }
    private void updateSelection(string id)
    {
        for (int i = 0; i < dict.Count; i++)
        {
            var value = dict.Values.ElementAt(i);
            var key = dict.Keys.ElementAt(i);
            if (dict.ContainsKey(id) && key == id)
            {
                value = selectedPattenitem;
            }
            else
            {
                value = unselecteditem;
            }
            dict.Remove(key);
            dict.Add(key, value);
        }

        StateHasChanged();
    }

}
